#ifdef HERZELEID_DESKTOP
 #if _MSC_VER
  #pragma once
 #endif

 #ifndef __HERZELEID_COREWINDOW_INCLUDED__
  #define __HERZELEID_COREWINDOW_INCLUDED__
  #include "HerzeleidCoreVirtualKeyStates.hxx"
  #include "HerzeleidApplicationModelCore.hxx"
  #include "HerzeleidCoreDispatcherInc.hxx"
  #include "HerzeleidVirtualKey.hxx"
  #include "HerzeleidCoreCursor.hxx"
  #include "HerzeleidTypedEvent.hxx"
  #include "HerzeleidRect.hxx"

HerzeleidAppModelCoreNamespaceBegin
	class CoreApplication;
	class CoreApplicationView;
HerzeleidAppModelCoreNamespaceEnd
HerzeleidUICoreNamespaceBegin 
	class WindowSizeChangedEventArgs; TinyTypeDecl( WindowSizeChangedEventArgs );
	class CharacterReceivedEventArgs; TinyTypeDecl( CharacterReceivedEventArgs );
	class VisibilityChangedEventArgs; TinyTypeDecl( VisibilityChangedEventArgs );
	class WindowActivatedEventArgs; TinyTypeDecl( WindowActivatedEventArgs );
	class CoreWindowEventArgs; TinyTypeDecl( WindowSizeChangedEventArgs );
	class PointerEventArgs; TinyTypeDecl( PointerEventArgs );
	class KeyEventArgs; TinyTypeDecl( KeyEventArgs );
HerzeleidUICoreNamespaceEnd;

// Defines a window object and its input events, and basic user interface behaviors
HerzeleidUICoreNamespaceBegin class CoreWindow
{
	friend class CoreDispatcher;
	friend HerzeleidAppModelCoreNamespaceImpl::CoreApplicationView;
	friend HerzeleidAppModelCoreNamespaceImpl::CoreApplication;
	typedef HerzeleidFoundationNamespaceImpl::Point Point;
	typedef HerzeleidFoundationNamespaceImpl::Rect Rect;
	TinyTypeDecl( Point );
	TinyTypeDecl( Rect );

protected: // Members

	static CoreWindow *s_pWindowForCurrentThread;

	CoreDispatcherPtr m_Handler;																	// The event dispatcher for the window.
	CoreCursor m_PointerCursor;																		// The cursor used by the window.
	Bool m_bIsInputEnabled;																			// Holds or sets a value that indicates whether input is enabled for the window. 
	InstanceHandle m_ModuleHandle;																	// Raw application handle.
	WindowHandle m_Handle;																			// Window raw handle. 
	Point m_PointerPosition;																		// The position of the pointer.
	Rect m_BoundingRect;																			// The bounding rectangle of the window.
	Bool m_bIsVisible;																				// Stores a value that indicates whether the window is visible. 

	Float32 m_fLogicalDpi;
	Float32 m_fXDpiScale;																			// Design x scale (assumes 96-Dpi pixels)
	Float32 m_fYDpiScale;																			// Design y scale (assumes 96-Dpi pixels)
	Bool m_bIsFullscreen;																			// Indicates whether the window is in the fullscreen mode. 

	CoreWindow();
	void RegisterWindow();
	void DestroyWindow();

public: // Events And Properties
	
	mutable Foundation::TypedEvent<CoreWindow, VisibilityChangedEventArgs>		VisibilityChanged;		// Is fired when the window visibility is changed. 
	mutable Foundation::TypedEvent<CoreWindow, WindowSizeChangedEventArgs>		SizeChanged;			// Is fired when the window size is changed.
	mutable Foundation::TypedEvent<CoreWindow, WindowActivatedEventArgs>		Activated;				// Is fired when the window completes activation or deactivation.
	mutable Foundation::TypedEvent<CoreWindow, CoreWindowEventArgs>				Closed;					// Is fired when a window is closed (or if the app terminates).
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerWheelChanged;	// Occurs when the mouse wheel is rotated.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerCaptureLost;		// Occurs when a pointer moves to another window.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerReleased;		// Occurs when a mouse button is released or the finger or pen is lifted from the digitizer surface.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerPressed;			// Occurs when a mouse button is clicked or the digitizer surface has been touched by a finger or pen.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerEntered;			// Occurs when a pointer moves into the bounding box of the window.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerExited;			// Occurs when the pointer moves outside the bounding box of the window.
	mutable Foundation::TypedEvent<CoreWindow, PointerEventArgs>				PointerMoved;			// Specifies the event that occurs when a pointer moves within the bounding box of the window.
	mutable Foundation::TypedEvent<CoreWindow, CharacterReceivedEventArgs>		CharacterReceived;		// Is fired when a new character is received by the input queue.
	mutable Foundation::TypedEvent<CoreWindow, KeyEventArgs>					KeyDown;				// Is fired when a non-system key is pressed.
	mutable Foundation::TypedEvent<CoreWindow, KeyEventArgs>					KeyUp;					// Is fired when a non-system key is released after a press.

	DeclGetSetPropOnly( CoreCursorConstPtrConst, PointerCursor );									// Gets or sets the cursor used by the window.
	DeclGetPropOnly( PointConstPtrConst, PointerPosition );											// Gets the position of the pointer. 
	DeclGetPropOnly( CoreDispatcherPtrConst, Dispatcher );											// Gets the event dispatcher for the window.
	DeclGetPropOnly( RectConstPtrConst, Bounds );													// Gets the bounding rectangle of the window.
	DeclGetSetPropOnly( BoolConst, IsInputEnabled );												// Gets or sets a value that indicates whether input is enabled for the window. 
	DeclGetPropOnly( BoolConst, Visible );															// Gets a value that indicates whether the window is visible. 
	inline DeclConstTypedGetterFor( CoreCursorConstPtrConst, PointerCursor ) { return &m_PointerCursor; }	// Gets the cursor used by the window.
	inline DeclConstTypedGetterFor( PointConstPtrConst, PointerPosition ) { return &m_PointerPosition; }									// Gets the position of the pointer. 
	inline DeclTypedGetterFor( CoreDispatcherPtrConst, Dispatcher ) { return m_Handler; }										// Gets the event dispatcher for the window.
	inline DeclTypedSetterFor( CoreCursorConstPtr, PointerCursor ) { m_PointerCursor = (*Value); }										// Sets the cursor used by the window.
	inline DeclConstTypedGetterFor( RectConstPtrConst, Bounds ) { return &m_BoundingRect; }											// Gets the bounding rectangle of the window.
	inline DeclConstTypedGetterFor( BoolConst, IsInputEnabled ) { return m_bIsInputEnabled; }											// Gets or sets a value that indicates whether input is enabled for the window. 
	inline DeclTypedSetterFor( BoolConstRef, IsInputEnabled ) { m_bIsInputEnabled = Value; }												// Gets or sets a value that indicates whether input is enabled for the window. 
	inline DeclConstTypedGetterFor( BoolConst, Visible ) { return m_bIsVisible; }													// Gets a value that indicates whether the window is visible. 

	static CoreWindow *GetForCurrentThread();

public: // Functionality

	// Gets the state of a key. 
	// (Works good for keyboard input)
	CoreVirtualKeyStatesConst GetKeyState( 
		_In_ System::VirtualKeyConstRef VirtualKey // Virtual key code
		) const;
	// Returns the state of a virtual key asynchronously. 
	// (Works good for mouse input, but the user should check whether the buttons were swapped or not)
	CoreVirtualKeyStatesConst GetAsyncKeyState( 
		_In_ System::VirtualKeyConstRef VirtualKey // Virtual key code
		) const;
	
	// Enables pointer capture for the window.
	void SetPointerCapture(
		) const;
	// Disables pointer capture for the window.
	void ReleasePointerCapture(
		) const;

	// Activates the window.
	void Activate(
		);
	// Closes the window and exits the message loop. 
	void Close(
		);

	WindowHandle GetHandle()
	{
		return m_Handle;
	}

	Float32 GetLogicalDpi()
	{
		return m_fLogicalDpi;
	}

} HerzeleidUICoreNamespaceEnd;

 #endif // !HERZELEID_COREWINDOW_INCLUDED__
#endif // !HERZELEID_DESKTOP
